﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace treeTest
{
    public partial class Form1 : Form
    {


        private List<Category> items = new List<Category>();
        public Form1()
        {
            InitializeComponent();
        }
        /*
         * dataSet1 has a table with 3 columns
         * col#1=ID (int)
         * col#2=ParentID (int)
         * col#3=NodeText (string)
         */
        private void Form1_Load(object sender, EventArgs e)
        {
            // Load up a dataset with values - usually from a database, but
            // here I can show the data without using a real database.
            dataSet1.Tables[0].Rows.Add(1, 0, "First Node");
            dataSet1.Tables[0].Rows.Add(3, 1, "Node 3.1");
            dataSet1.Tables[0].Rows.Add(4, 1, "Node 4.1");
            dataSet1.Tables[0].Rows.Add(5, 0, "Node 5.0");
            dataSet1.Tables[0].Rows.Add(6, 5, "Node 6.5");
            dataSet1.Tables[0].Rows.Add(7, 5, "Node 7.5");
            dataSet1.Tables[0].Rows.Add(8, 5, "Node 8.5");
            dataSet1.Tables[0].Rows.Add(9, 5, "Node 9.5");
            dataSet1.Tables[0].Rows.Add(10, 6, "Node 10.6");
            dataSet1.Tables[0].Rows.Add(11, 6, "Node 11.6");
            dataSet1.Tables[0].Rows.Add(12, 11, "Node 12.11");
            dataSet1.Tables[0].Rows.Add(13, 11, "Node 13.11");
            dataSet1.Tables[0].Rows.Add(14, 11, "Node 14.11");
            dataSet1.Tables[0].Rows.Add(15, 11, "Node 15.11");
            // Populate the items array of Catagory from the dataset
            foreach (DataRow dr in dataSet1.Tables[0].Rows)
                items.Add(new Category((int)dr[0], (int)dr[1], (string)dr[2]));

            // Build the treeview from the catagory list
            buildtree();

            

        }

        private void buildtree()
        {
            treeView1.Nodes.Clear();    // Clear any existing items
            treeView1.BeginUpdate();    // prevent overhead and flicker
            LoadBaseNodes();            // load all the lowest tree nodes
            treeView1.EndUpdate();      // re-enable the tree
            treeView1.Refresh();        // refresh the treeview display
        }

        private void LoadBaseNodes()
        {
            int baseParent = 0;                 // Find the lowest root category parent value
            TreeNode node;
            foreach (Category cat in items)
            {
                if (cat.ParentID < baseParent)
                    baseParent = cat.ParentID;
            }
            foreach (Category cat in items)         // iterate through the categories
            {
                if (cat.ParentID == baseParent)     // found a matching root item
                {
                    node = treeView1.Nodes.Add(cat.NodeText); // add it to the tree
                    node.Tag = cat;                 // send the category into the tag for future processing
                    getChildren(node);              // load all the children of this node
                }
            }
        }

        // recursive tree loader. Passes back in a node to retireve its childre
        // until there are no more children for this node.
        private void getChildren(TreeNode node)
        {
            TreeNode Node = null;
            Category nodeCat = (Category)node.Tag;  // get the category for this node
            foreach (Category cat in items)         // locate all children of this category
            {
                if (cat.ParentID == nodeCat.ID)     // found a child
                {
                    Node = node.Nodes.Add(cat.NodeText);    // add the child
                    Node.Tag = cat;                         // set its tag to its category
                    getChildren(Node);                      // find this child's children
                }
            }
        }
    }

    class Category
    {
        public int ID;
        public int ParentID;
        public string NodeText;
        public Category(int ID, int ParentID, string NodeText)
        {
            this.ID = ID;
            this.ParentID = ParentID;
            this.NodeText = NodeText;
        }
        public override string ToString()
        {
            return this.NodeText;
        }
    }
}
